package com.paraz.cst;

import static org.junit.Assert.*;

import java.util.concurrent.atomic.AtomicBoolean;

import org.junit.Test;

/**
 * Test without any dependency injection tools.
 * @author mparaz
 *
 */
public class SyncCstLooperTestCase {
	/**
	 * String to compare.
	 */
	private final String STR = "Hello World";

	
	// Use an AtomicBoolean since we can make it final and accessible from inner classes.
	final AtomicBoolean isCalled = new AtomicBoolean(); 
	
	@Test
	public void testSyncLoop() {
		final TestCstProcessor<Object> processor = new TestCstProcessor<Object>(false);
		
		final SyncCstLooper looper = new SyncCstLooper();
		looper.setCstProcessor(processor);
		
		
		// Two-level layer of anonymous interfaces.
		// This is fine since we don't need to loop.
		final CstSocket cstSocket = new CstSocket() {

			public CstInput getCstInput() {
				return new CstInput() {
					public String read() throws CstException {
						return STR;
					}
				};
			}

			public CstOutput getCstOutput() {
				return new CstOutput() {
					public void write(String output) throws CstException {
						// Verify the output
						assertEquals(STR + SyncCstLooper.LINE_TERMINATOR, output);
						
						// Set the state, this was called.
						isCalled.set(true);
					}
				};
			}
		};
		

		// Fire. 
		looper.loop(true, cstSocket);
		
		// Verify that write() was called.
		// Avoid "Pass by Default."
		// write() called implies read() called.
		assertTrue(isCalled.get());

		isCalled.set(false);
		// Fire. 
		looper.loop(true, cstSocket);
	
	}
}
